/*
 * Created on 2 Apr 2007 by Andrew White
 */

package com.volatileshooter.networking.io;

import java.net.SocketAddress;

/*
 * This is the base packet class that all game packets will be defined
 * from. The default features of each packet are defined here.
 */
public class GamePacket {

    /** 
     * Character set to be used for all strings, set in this base class
     * so that the same encoding is used on all clients, rather than
     * the system default (which might vary per country). UTF-8 should cover
     * all required languages.
     */
    protected final String CHARSET = "UTF-8";
    
    /**
     * Light weight packet can be sent with no overhead of checking whether it
     * arrives successfully or not.
     */
    protected static final byte LIGHT = 0;

    /**
     * Heavy weight packet will make sure this packet arrives successfully.
     * Overhead is introduced in doing this though.
     */
    protected static final byte HEAVY = 1;
    
    /**
     * Static counter to give each packet a unique ID.
     */
    private static int COUNT = 0;

    /**
     * ID of sender.
     */
    public short clientId = 0;
    
    /**
     * ID of packet, this is used to keep track of what order packets were sent
     * once they are received since UDP packets may arrive out of order.
     */
    public int packetId = 0;
    
    /**
     * Event type this packet contains.
     */
    public byte event = 0;

    /**
     * Payload of packet.
     */
    public byte[] payload;

    /**
     * Address to send packet to or packet was received from.
     */
    public SocketAddress addr;

    /**
     * Light or heavy, whether to check if this packet arrives successfully or
     * not.
     */
    protected byte weight = GamePacket.LIGHT;
    
    /**
     * Time stamp of when this packet was sent.
     */
    protected long timestamp = 0;

    /**
     * Number of attempts made to send the packet.
     */
    protected int attempts = 0;

    /**
     * Constructs a new GamePacket with a unique ID.
     * 
     * @param clientId The clients Id
     * @param addr The socket address to send the packet to, or was received via
     */
    public GamePacket(short clientId, SocketAddress addr) {
        packetId = COUNT++;
        this.clientId = clientId;
        this.addr = addr;
    }
    
    /**
     * Copies the contents of the packet into a new packet, this is useful for
     * sending packets to multiple clients as we need to generate a new packet
     * to send per client.
     * 
     * @return Copy of packet
     */
    public GamePacket copy() {
        GamePacket packet = new GamePacket(clientId, addr);
        packet.payload = new byte[payload.length];
        System.arraycopy(payload, 0, packet.payload, 0, payload.length);
        packet.event = event;
        packet.weight = weight;
        return packet;
    }
    
}
